package com.wchat.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wchat.bean.entity.ChatMsgs;
import com.wchat.bean.entity.FriendMsgs;
import com.wchat.bean.entity.GroupMsgs;
import com.wchat.bean.model.MsgPayload;
import com.wchat.bean.model.body.ChatMsgBody;
import com.wchat.bean.model.body.EventBody;
import com.wchat.bean.model.enums.ChatTypeEm;
import com.wchat.bean.model.enums.HeaderTypeEm;
import com.wchat.bean.model.enums.TypeEm;
import com.wchat.mapper.ChatMsgsMapper;
import com.wchat.mapper.FriendMsgsMapper;
import com.wchat.mapper.GroupMsgsMapper;
import com.wchat.server.ClientManager;
import com.wchat.service.MessageService;
import com.wchat.utils.JwtUtil;
import com.wchat.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * @author : willian fu
 * @date : 2021/8/31
 */
@Slf4j
@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private ClientManager clientManager;

    @Autowired
    private GroupMsgsMapper groupMsgsMapper;

    @Autowired
    private FriendMsgsMapper friendMsgsMapper;

    @Autowired
    private ChatMsgsMapper chatMsgsMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public Object recallHistoryMsg(String msgId, ChatTypeEm type) {
        Integer userId = jwtUtil.jwtGetUser().getUserId();
        MsgPayload event = MsgPayload.builder().header(HeaderTypeEm.EVENT)
                .type(TypeEm.MSG_WITHDRAW)
                .body(EventBody.builder()
                        .id(msgId).userId(userId)
                        .type(type).build()).build();
        ChatMsgs chatMsgs = chatMsgsMapper.selectById(msgId);
        if (ChatTypeEm.GROUP.equals(type)){
            if (chatMsgs.getSender().equals(userId)){
                ClientManager.getGroups().getOrDefault(chatMsgs.getTarget(), Collections.emptySet()).forEach(g -> {
                    //撤回缓存消息及发送事件
                    long id = Long.parseLong(msgId);
                    clientManager.cleanMsgCatch(g, id);
                    clientManager.sendChatMsgQos2(userId, event);
                });
            }else {
                return R.badRequest("撤回失败");
            }
        }else {
            if (chatMsgs.getSender().equals(userId)){
                clientManager.cleanMsgCatch(chatMsgs.getTarget(), Long.parseLong(msgId));
                clientManager.sendChatMsgQos2(userId, event);
            }else {
                return R.badRequest("撤回失败");
            }
        }
        log.info("用户[{}]撤回消息[{}]成功", userId, msgId);
        return R.ok("撤回成功");
    }

    @Override
    public Object getHistoryMsg(Integer size, Boolean sended, ChatTypeEm type, String msgId, Integer id) {
        Integer myId = jwtUtil.jwtGetUser().getUserId();
        String condition = "";
        if (StrUtil.isNotBlank(msgId)){
            condition = " AND created < (SELECT created FROM chat_msgs WHERE msg_id = " + msgId + ") " ;
        }
        return R.ok(chatMsgsMapper.getHistoryMsg(myId, id, condition, type.toString(), size, sended));
    }

    @Override
    public Object sendMsg(MsgPayload msgPayload) {
        Integer userId = jwtUtil.jwtGetUser().getUserId();
        try {
            ((Map)msgPayload.getBody()).put("userId", userId);
            clientManager.sendChatMsgQos2(userId, msgPayload);
        } catch (Exception e) {
            log.error("用户[{}]发送消息失败", userId, e);
        }
        return R.ok("发送成功");
    }

    @Override
    public Object confirmMsgRevSuccess(Set<String> msgIds) {
        chatMsgsMapper.update(ChatMsgs.builder().isSend(true).build(),
                new QueryWrapper<ChatMsgs>().in("msg_id", msgIds));
        return R.ok("确认完成");
    }
}
